﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Text;
using System.Web;

namespace Aspfm.Main
{
    public class BaseAshx : IHttpHandler
    {
        public const string Extension = ".aspfm";

        public static void AspfmRequest(HttpContext context)
        {
            Request(context);
        }

        private static void Request(HttpContext context)
        {
            PageTool.BeginRequestLogin();
            AspfmModel dynobj = GetRequestDynObj(context);
            ExecAspfm(context, dynobj);
        }

        public static void ExecAspfm(HttpContext context, AspfmModel dynobj)
        {
            if (dynobj != null && dynobj.Values.ContainsKey("fmparams.Dll")
                && dynobj.Values.ContainsKey("fmparams.Class")
                && dynobj.Values.ContainsKey("fmparams.Active"))
            {
                string dllname = CurrentPath(true) + dynobj.GetPropertyValue("fmparams.Dll").ToString().Trim() + ".dll";
                string AspfmPlugindll = "";
                if (!File.Exists(dllname))
                {
                    AspfmPlugindll = CurrentPath(true) + "AspfmPlugin/" + MySecurity.EncryptSHA1(dynobj.GetPropertyValue("fmparams.Dll").ToString().Trim());
                }
                if (File.Exists(dllname) || File.Exists(AspfmPlugindll))
                {
                    string classname = dynobj.GetPropertyValue("fmparams.Class").ToString().Trim();
                    string active = dynobj.GetPropertyValue("fmparams.Active").ToString().Trim();
                    Type type = null;
                    object objcache = CacheHelper.GetCache(dllname + classname);
                    if (objcache != null && objcache is Type)
                    {
                        type = (Type)objcache;
                    }
                    if (type == null)
                    {
                        if (File.Exists(dllname))
                        {
                            System.Reflection.Assembly ass = System.Reflection.Assembly.LoadFrom(dllname);
                            type = ass.GetType(classname);
                            if (type != null)
                            {
                                CacheHelper.SetCache(dllname + classname, type, dllname);
                            }
                        }
                        else if (File.Exists(AspfmPlugindll))
                        {
                            type = Aspfm.Factory.FactoryObj.AspfmGetype(AspfmPlugindll, classname);
                            if (type != null)
                            {
                                CacheHelper.SetCache(dllname + classname, type, AspfmPlugindll);
                            }
                        }
                    }
                    if (type != null)
                    {
                        object obj = (object)Activator.CreateInstance(type);
                        if (obj is IMainController)
                        {
                            if (CheckRoleAction(context, dynobj))
                            {
                                IMainController mainmvc = (IMainController)obj;
                                mainmvc.Init(context, new UserIdentity(), dynobj);
                                mainmvc.MvcController(active.ToLower());
                            }
                        }
                        else
                        {
                            string html = "在动态库：" + dllname + "中，类：" + classname + "没有继承IMainController接口。";
                            ReturnHtml(html, context);
                        }
                    }
                    else
                    {
                        string html = "在动态库：" + dllname + "中，找不到类：" + classname;
                        ReturnHtml(html, context);
                    }
                }
                else
                {
                    ReturnHtml("找不到动态库：" + dllname, context);
                }
            }
            else
            {
                string htmldate = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                if (dynobj != null)
                {
                    string isnumber = dynobj.GetPropertyValueStr("isnumber");
                    if (isnumber == "true")
                    {
                        htmldate = DateTime.Now.ToString("yyyyMMddHHmmss");
                    }
                }
                ReturnHtml(htmldate, context);
            }
        }

        public static bool CheckRoleAction(HttpContext context, AspfmModel dynobj)
        {
            string dllname = dynobj.GetPropertyValue("fmparams.Dll").ToString().Trim();
            string classname = dynobj.GetPropertyValue("fmparams.Class").ToString().Trim();
            string active = dynobj.GetPropertyValue("fmparams.Active").ToString().Trim();


            Aspfm.Main.UserIdentity user = new Aspfm.Main.UserIdentity();
            
            AspfmRightModel AspfmRightAll = AspfmRight.XmlReaderAspfmRight();
            if (AspfmRightAll != null)
            {
                bool hadRight = true;
                foreach (AspfmRightAction raction in AspfmRightAll.Actions)
                {
                    if (raction.dll == "*" || raction.dll == dllname)
                    {
                        if (raction.clss == "*" || raction.clss == classname)
                        {
                            if (raction.cmd == "*" || raction.cmd == active)
                            {
                                if (raction.SysRoleLevel == "*")
                                {
                                    hadRight = true;
                                }
                                else
                                {
                                    hadRight = false;
                                    if (!string.IsNullOrEmpty(user.SysRoleLevel))
                                    {
                                        string alllevel = "," + raction.SysRoleLevel + ",";
                                        string[] strlevels = user.SysRoleLevel.Split(',');
                                        foreach (string str in strlevels)
                                        {
                                            if (alllevel.Contains("," + str + ","))
                                            {
                                                hadRight = true;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                if (hadRight)
                {
                    if (GetHttpIsPost(context) == false)
                    {
                        hadRight = false;
                        foreach (AspfmRightAction raction in AspfmRightAll.Get)
                        {
                            if (raction.dll == "*" || raction.dll == dllname)
                            {
                                if (raction.clss == "*" || raction.clss == classname)
                                {
                                    if (raction.cmd == "*" || raction.cmd == active)
                                    {
                                        hadRight = true;
                                    }
                                }
                            }
                        }
                        if (hadRight == false)
                        {
                            ReturnHtml("该控制器只允许Post方式访问。DLL：" + dllname + " CLASS：" + classname + " Action：" + active, context);
                        }
                    }
                    else
                    {
                        string url = "";
                        bool isOrigin = false;
                        if (context != null)
                        {
                            if (context.Request.UrlReferrer==null)
                            {
                                isOrigin = true;
                            }
                            else
                            {
                                url = context.Request.UrlReferrer.OriginalString;
                                if (context.Request.UrlReferrer.Authority != context.Request.Url.Authority)
                                {
                                    isOrigin = true;
                                }
                            }
                        }
                        hadRight = true;
                        if (isOrigin)
                        {
                            hadRight = false;
                            foreach (AspfmRightAction raction in AspfmRightAll.UrlAction)
                            {
                                if (url.StartsWith(raction.url) || raction.url == "*")
                                {
                                    if (raction.dll == "*" || raction.dll == dllname)
                                    {
                                        if (raction.clss == "*" || raction.clss == classname)
                                        {
                                            if (raction.cmd == "*" || raction.cmd == active)
                                            {
                                                hadRight = true;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        if (hadRight == false)
                        {
                            ReturnHtml("该控制器不允许在外站：" + url + "访问。DLL：" + dllname + " CLASS：" + classname + " Action：" + active, context);
                        }
                    }
                }
                else
                {
                    ReturnHtml("该用户该控制器的访问权限。DLL：" + dllname + " CLASS：" + classname + " Action：" + active, context);
                }
                return hadRight;
            }
            return true;
        }
        public static string GetLocalPath(System.Web.HttpContext Context, AspfmModel RequestDynObj,bool isUseReferrer=true)
        {
            string LocalPath = "";
            string str = "";
            if (Context != null)
            {
                if (Context.Request.UrlReferrer != null)
                {
                    LocalPath = Context.Request.UrlReferrer.LocalPath;
                    if (isUseReferrer == false)
                    {
                        LocalPath = Context.Request.Url.LocalPath;
                    }
                }
                else
                {
                    LocalPath = "/";
                }
                str = Context.Request.ApplicationPath;
            }
            if (LocalPath == "/")
            {
                LocalPath = LocalPath + RequestDynObj.GetPropertyValueStr("defaulthtml");
            }

            if (str.Trim('/') != "" && LocalPath.StartsWith(str))
            {
                LocalPath = LocalPath.Substring(str.Length);
            }
            LocalPath = System.Web.HttpUtility.HtmlDecode(LocalPath);
            return LocalPath;
        }
        public static bool GetHttpIsPost(HttpContext context)
        {
            if (context != null)
            {
                return context.Request.HttpMethod.ToUpper() == "POST";
            }
            return false;
        }

        public static void ReturnHtml(string htmldate, HttpContext context)
        {
            if (context != null)
            {
                context.Response.AddHeader("Server", "Aspfm Server V0.0.1");
                context.Response.AddHeader("Access-Control-Allow-Origin", "*"); 
                context.Response.ContentType = "text/plain";
                context.Response.Write(htmldate);
                context.Response.End();
            }
        }
        public static AspfmModel GetRequestDynObj(HttpContext context)
        {
            AspfmModel RequestDynObj = new AspfmModel();
            if (context != null)
            {
                if (context != null && context.Request != null)
                {
                    System.Collections.Specialized.NameValueCollection nvlist = context.Request.Form;
                    SetValue(RequestDynObj, nvlist);
                    System.Collections.Specialized.NameValueCollection nvlist1 = HttpUtility.ParseQueryString(context.Request.Url.Query);
                    SetValue(RequestDynObj, nvlist1);
                }
            }
            RequestDynObj.SetPropertyValue("sysuserno", PageTool.GetCurrentUser()._uno);//注册登录用户Id
            return RequestDynObj;
        }

        private static void SetValue(AspfmModel RequestDynObj, System.Collections.Specialized.NameValueCollection nvlist, string beforestr="")
        {
            if (nvlist != null && nvlist.Count > 0)
            {
                int count = nvlist.Count;
                for (int i = 0; i < count; i++)
                {
                    if (nvlist.AllKeys[i] != null)
                    {
                        string key = nvlist.AllKeys[i].Replace("]", "").Replace("[", ".");//.ToLower();
                        string keyvalue = nvlist[nvlist.AllKeys[i]];
                        if (keyvalue == "undefined")
                        { keyvalue = ""; }
                        if (!string.IsNullOrEmpty(keyvalue))
                        {
                            keyvalue = System.Web.HttpUtility.HtmlDecode(keyvalue);
                        }
                        RequestDynObj.SetPropertyValue(beforestr + key, keyvalue);
                    }
                }
            }
        }

        public static string CurrentPath(bool hadBin = false)
        {
            string str = "";
            object CurrentPathObj = CacheHelper.GetCache("Aspfm.CurrentPath.Bin");
            if (CurrentPathObj != null)
            {
                str = CurrentPathObj.ToString();
            }
            else
            {
                str = System.Reflection.Assembly.GetExecutingAssembly().CodeBase;
                int start = 8;// 去除file:///  
                int end = str.LastIndexOf('/');// 去除文件名xxx.dll及文件名前的/  
                str = str.Substring(start, end - start + 1);
                CacheHelper.SetCache("Aspfm.CurrentPath.Bin", str);
            }
            if (hadBin)
            {
                return str;
            }
            else
            {
                if (AppDomain.CurrentDomain.BaseDirectory.Replace("\\", "/").Trim('/') == str.Replace("\\", "/").Trim('/'))
                {
                    return Directory.GetParent(str.Trim('/').Trim('\\')).FullName;
                }
            }
            return AppDomain.CurrentDomain.BaseDirectory;
        }

        public static string GetContentType(string str)
        {
            switch (str.ToLower())
            {
                case ".txt": return "text/plain";
                case ".jpg": return "image/jpeg";
                case ".png": return "image/png";
                case ".pdf": return "application/pdf";
                default: return "application/octet-stream";
            }
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }

        public void ProcessRequest(HttpContext context)
        {
            context.Request.ValidateInput();
            BaseAshx.AspfmRequest(context);
        }
    }
}
